/**
* Copyright (C) 2019-2021 Xilinx, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may
* not use this file except in compliance with the License. A copy of the
* License is located at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

#include "common.h"

void Filter2D(const char coeffs[FILTER_V_SIZE][FILTER_H_SIZE],
              float factor,
              short bias,
              unsigned short width,
              unsigned short height,
              unsigned char* src,
              unsigned char* dst) {
    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            // Apply 2D filter to the pixel window
            int sum = 0;
            for (int row = 0; row < FILTER_V_SIZE; row++) {
                for (int col = 0; col < FILTER_H_SIZE; col++) {
                    unsigned char pixel;
                    int xoffset = (x + col - (FILTER_H_SIZE / 2));
                    int yoffset = (y + row - (FILTER_V_SIZE / 2));
                    // Deal with boundary conditions : clamp pixels to 0 when outside of image
                    if ((xoffset < 0) || (xoffset >= width) || (yoffset < 0) || (yoffset >= height)) {
                        pixel = 0;
                    } else {
                        pixel = src[yoffset * width + xoffset];
                    }
                    sum += pixel * coeffs[row][col];
                }
            }

            // Normalize and saturate result
            unsigned char outpix = MIN(MAX((int(factor * sum) + bias), 0), 255);

            // Write output
            dst[y * width + x] = outpix;
        }
    }
}
